curl --request POST \
--url http://localhost:50002/reservations \
--header 'Content-Type: application/json' \
--data '
{
"seatId": "<string>",
"customerId": "<string>"
}
'{
"reservationId": "8bf7fffc-9ff5-401c-9d2d-86f525f42e40",
"seatId": "550e8400-e29b-41d4-a716-446655440002",
"customerId": "customer-123",
"expiresAt": "2026-02-24T16:15:00Z",
"status": "active"
}
Reserve a seat with a 15-minute TTL using distributed Redis locking
curl --request POST \
--url http://localhost:50002/reservations \
--header 'Content-Type: application/json' \
--data '
{
"seatId": "<string>",
"customerId": "<string>"
}
'{
"reservationId": "8bf7fffc-9ff5-401c-9d2d-86f525f42e40",
"seatId": "550e8400-e29b-41d4-a716-446655440002",
"customerId": "customer-123",
"expiresAt": "2026-02-24T16:15:00Z",
"status": "active"
}
Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JostinAlvaradoS/ticketing_project_week0/llms.txt
Use this file to discover all available pages before exploring further.
reservation-created event to be processed before adding the seat to the cart. Failing to wait will result in a “Reservation not found” error.lock:seat:{seatId}SET NX with token-based releaseCreateReservationCommandHandler.cs:19-21,41-48:
private const string RedisLockKeyPrefix = "lock:seat:";
private const int LockExpirySeconds = 30;
private const int ReservationTTLMinutes = 15;
var lockKey = $"{RedisLockKeyPrefix}{request.SeatId:N}";
var lockToken = await _redisLock.AcquireLockAsync(lockKey, TimeSpan.FromSeconds(LockExpirySeconds));
if (lockToken is null)
{
throw new InvalidOperationException($"Could not acquire lock for seat {request.SeatId}. Seat may be reserved or locked.");
}
reservation-created event to Kafka:
reservation-created{seatId} (ensures ordering per seat)CreateReservationCommandHandler.cs:105-127:
private async Task PublishReservationCreatedEvent(Reservation reservation, Seat seat, CancellationToken cancellationToken)
{
var @event = new ReservationCreatedEvent(
EventId: Guid.NewGuid().ToString("D"),
ReservationId: reservation.Id.ToString("D"),
CustomerId: reservation.CustomerId,
SeatId: reservation.SeatId.ToString("D"),
SeatNumber: $"{seat.Section}-{seat.Row}-{seat.Number}",
Section: seat.Section,
BasePrice: 0m,
CreatedAt: reservation.CreatedAt.ToString("O"),
ExpiresAt: reservation.ExpiresAt.ToString("O"),
Status: reservation.Status
);
var json = JsonSerializer.Serialize(@event, jsonOptions);
await _kafkaProducer.ProduceAsync("reservation-created", json, reservation.SeatId.ToString("N"));
}
"550e8400-e29b-41d4-a716-446655440002""customer-123", "jose@example.com"Content-Type: application/json
Accept: application/json
"2026-02-24T16:15:00Z""active" - Reservation is valid and active"expired" - Reservation has expired (after 15 minutes)"consumed" - Reservation was used to create an ordercurl -X POST http://localhost:50002/reservations \
-H "Content-Type: application/json" \
-d '{
"seatId": "550e8400-e29b-41d4-a716-446655440002",
"customerId": "customer-123"
}'
{
"reservationId": "8bf7fffc-9ff5-401c-9d2d-86f525f42e40",
"seatId": "550e8400-e29b-41d4-a716-446655440002",
"customerId": "customer-123",
"expiresAt": "2026-02-24T16:15:00Z",
"status": "active"
}
seatId formatcustomerIdseatId is a valid UUID but doesn’t correspond to any seatWait for Event Processing
reservation-created event to be consumed by the Ordering serviceInventory.Api/Endpoints/ReservationEndpoints.cs:17-56Inventory.Application/UseCases/CreateReservation/CreateReservationCommandHandler.csInventory.Domain/Entities/Reservation.csInventory.Infrastructure/Locking/RedisLock.csCREATE TABLE Reservations (
Id UUID PRIMARY KEY,
SeatId UUID NOT NULL,
CustomerId VARCHAR NOT NULL,
CreatedAt TIMESTAMP NOT NULL,
ExpiresAt TIMESTAMP NOT NULL,
Status VARCHAR NOT NULL
);